package com.heu.blood.analysis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.heu.blood.analysis.entity.BloodTestTransfusionEntity;
import com.heu.blood.analysis.entity.TestResult;
import com.heu.blood.analysis.service.BloodSampleInfoInpatientlabService;
import com.heu.blood.analysis.vo.BloodSampleInpatientlabReportVo;
import com.heu.blood.analysis.vo.BloodSampleTransfusionReportVo;
import com.heu.blood.analysis.vo.BloodTestInpatientlabVo;
import com.heu.blood.analysis.vo.BloodTestTransfusionVo;
import com.heu.blood.common.commponent.DictionaryLoader;
import com.heu.blood.common.enums.DictDataEnum;
import com.heu.blood.globalExceptionHandler.MyException;
import com.heu.blood.match.exception.TimeException;
import com.heu.blood.transfusion.entity.TransfusionAgreementEntity;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;

import com.heu.blood.analysis.dao.BloodTestInpatientlabDao;
import com.heu.blood.analysis.entity.BloodTestInpatientlabEntity;
import com.heu.blood.analysis.service.BloodTestInpatientlabService;

import static com.heu.blood.common.enums.CommonEnum.IF_SHOW;


@Service("bloodTestInpatientlabService")
public class BloodTestInpatientlabServiceImpl extends ServiceImpl<BloodTestInpatientlabDao, BloodTestInpatientlabEntity> implements BloodTestInpatientlabService {

    @Autowired
    BloodTestInpatientlabDao bloodTestInpatientlabDao;

    @Autowired
    BloodSampleInfoInpatientlabService bloodSampleInfoInpatientlabService;

    @Autowired
    private DictionaryLoader dictionaryLoader;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<BloodTestInpatientlabEntity> page = this.page(
                new Query<BloodTestInpatientlabEntity>().getPage(params),
                new QueryWrapper<BloodTestInpatientlabEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils selectSampleTestPage(Map<String, Object> params) {
        //        创建bloodTestInpatientlabVo接收前端的查询条件
        BloodTestInpatientlabVo bloodTestInpatientlabVo = new BloodTestInpatientlabVo();
        if (Strings.isNotBlank((String) params.get("bloodTestInpatientlabId"))) {
            bloodTestInpatientlabVo.setBloodTestInpatientlabId((String) params.get
                    ("bloodTestInpatientlabId")); // 检测单号
        }
//        1.get2.set3.get
        if (Strings.isNotBlank((String) params.get("bloodSampleInfoInpatientlabId"))) {
            bloodTestInpatientlabVo.setBloodSampleInfoInpatientlabId((String) params.get
                    ("bloodSampleInfoInpatientlabId")); // 输血申请的血液样本ID
        }
        if (Strings.isNotBlank((String) params.get("inspector"))) {
            bloodTestInpatientlabVo.setInspector((String) params.get
                    ("inspector"));// 检测人
        }
        if (Strings.isNotBlank((String) params.get("patientId"))) {
            bloodTestInpatientlabVo.setPatientId((String) params.get
                    ("patientId"));// 根据病人编号查询
        }
        if (Strings.isNotBlank((String) params.get("patientName"))) {
            bloodTestInpatientlabVo.setPatientName((String) params.get
                    ("patientName"));// 根据病人姓名查询
        }
//        if (Strings.isNotBlank((String) params.get("collector"))) {
//            bloodTestInpatientlabVo.setCollector((String) params.get
//                    ("collector")); // 采血者
//        }
//        if (Strings.isNotBlank((String) params.get("recipient"))) {
//            bloodTestInpatientlabVo.setRecipient((String) params.get
//                    ("recipient")); // 接收者
//        }
        if (Strings.isNotBlank((String) params.get("reason"))) {
            bloodTestInpatientlabVo.setReason((String) params.get
                    ("reason")); // 退血原因
        }
        if (Strings.isNotBlank((String) params.get("department"))) {
            bloodTestInpatientlabVo.setDepartment((String) params.get
                    ("department")); // 部门
        }
        if (Strings.isNotBlank((String) params.get("applicationProject"))) {
            bloodTestInpatientlabVo.setApplicationProject((String) params.get
                    ("applicationProject")); // 申请项目
        }
//        if (Strings.isNotBlank((String) params.get("inspectStatus"))) {
//            bloodTestInpatientlabVo.setInspectStatus((String) params.get
//                    ("inspectStatus")); // 项目状态
//        }

        // 接收时间范围条件
        String inspectStartTime = null; // 检测时间左边界
        String inspectEndTime = null; // 检测时间有边界
        String receivedStartTime = null; // 接收时间左边界
        String receivedEndTime = null; // 接收时间右边界
        String collectStartTime = null; // 采血时间左边界
        String collectEndTime = null; // 采血时间右边界

        if (Strings.isNotBlank((String) params.get("inspectStartTime"))){
            inspectStartTime = (String) params.get("inspectStartTime");
        }
        if (Strings.isNotBlank((String) params.get("inspectEndTime"))){
            inspectEndTime = (String) params.get("inspectEndTime");
        }
        if (Strings.isNotBlank(inspectStartTime) && Strings.isNotBlank(inspectEndTime)) {
            if (inspectStartTime.compareTo(inspectEndTime) > 0) {
                throw new MyException(TimeException.TIME_OUTLINE);
            }
        }
        if (Strings.isNotBlank((String) params.get("receivedStartTime"))){
            receivedStartTime = (String) params.get("receivedStartTime");
        }
        if (Strings.isNotBlank((String) params.get("receivedEndTime"))){
            receivedEndTime = (String) params.get("receivedEndTime");
        }
        if (Strings.isNotBlank(receivedStartTime) && Strings.isNotBlank(receivedEndTime)) {
            if (receivedStartTime.compareTo(receivedEndTime) > 0) {
                throw new MyException(TimeException.TIME_OUTLINE);
            }
        }
        if (Strings.isNotBlank((String) params.get("collectStartTime"))){
            collectStartTime = (String) params.get("collectStartTime");
        }
        if (Strings.isNotBlank((String) params.get("collectEndTime"))){
            collectEndTime = (String) params.get("collectEndTime");
        }
        if (Strings.isNotBlank(collectStartTime) && Strings.isNotBlank(collectEndTime)) {
            if (collectStartTime.compareTo(collectEndTime) > 0) {
                throw new MyException(TimeException.TIME_OUTLINE);
            }
        }
        QueryWrapper<BloodTestInpatientlabVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                getBloodTestInpatientlabId()), "bt.blood_test_inpatientlab_id", bloodTestInpatientlabVo.
                getBloodTestInpatientlabId())
                .eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                        getBloodSampleInfoInpatientlabId()), "bt.blood_sample_info_inpatientlab_id", bloodTestInpatientlabVo.
                        getBloodSampleInfoInpatientlabId())
                .eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                        getInspector()), "bt.inspector", bloodTestInpatientlabVo.
                        getInspector())
                .eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                        getPatientId()), "bs.patient_id", bloodTestInpatientlabVo.
                        getPatientId())
                .eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                        getPatientName()), "bs.patient_name", bloodTestInpatientlabVo.
                        getPatientName())
                .eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                        getReason()), "bs.reason", bloodTestInpatientlabVo.
                        getReason())
                .eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                        getDepartment()), "bs.department", bloodTestInpatientlabVo.
                        getDepartment())
                .eq(Strings.isNotBlank(bloodTestInpatientlabVo.
                        getApplicationProject()), "bt.application_project", bloodTestInpatientlabVo.
                        getApplicationProject())
                .ge(Strings.isNotBlank(inspectStartTime), "bt.inspect_time", inspectStartTime)
                .le(Strings.isNotBlank(inspectEndTime), "bt.inspect_time", inspectEndTime)
                .ge(Strings.isNotBlank(collectStartTime), "bs.collect_time", collectStartTime)
                .le(Strings.isNotBlank(collectEndTime), "bs.collect_time", collectEndTime)
                .ge(Strings.isNotBlank(receivedStartTime), "bs.received_time", receivedStartTime)
                .le(Strings.isNotBlank(receivedEndTime), "bs.received_time", receivedEndTime);;
        IPage<BloodTestInpatientlabVo> page = bloodTestInpatientlabDao.selectSampleTestPage(
                new Query<BloodTestInpatientlabVo>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    public Map<BloodSampleInpatientlabReportVo, List<TestResult>> queryTestResult(String bloodSampleId) {
//        1.获取血液样本信息
        BloodSampleInpatientlabReportVo bloodSampleInpatientlabReportVo = bloodSampleInfoInpatientlabService.
                selectSampleReport(bloodSampleId);
        if (bloodSampleInpatientlabReportVo == null) {
            return null;
        }
//        2.获取检测表信息
        List<BloodTestInpatientlabEntity> bloodTestEntityList = this.getBySampleId(bloodSampleId);
        if (bloodTestEntityList == null){
            return null;
        }
        // 3、设定一个List来存放查询出来的检测项目和检测结果<检测项目，<检测项目价格，检测结果>>
        List<TestResult> testResults = new ArrayList<>();

        Map<String, Map<String, String[]>> dict = dictionaryLoader.getDict();
        // 4、查询出相关检测
        for(BloodTestInpatientlabEntity bloodTestInpatientlabEntity:bloodTestEntityList) {
            //创建TestResult类用于存放检测结果
            TestResult testResult = new TestResult();
            //写入检测项目,检测结果,检测次数,价格
            testResult.setProjectName(dict.get(DictDataEnum.PAYMENT_PROJECT.code()).get(bloodTestInpatientlabEntity.getApplicationProject())[0]);
            testResult.setResult(bloodTestInpatientlabEntity.getProjectResult());
            testResult.setCount(bloodTestInpatientlabEntity.getCount());
            testResult.setPrice(bloodTestInpatientlabEntity.getPrice());
            //将检测结果保存
            testResults.add(testResult);
        }
        // 5、再将相关检测与病人信息封装成一个新的对象返回
        Map<BloodSampleInpatientlabReportVo, List<TestResult>> report = new HashMap<>();
        report.put(bloodSampleInpatientlabReportVo, testResults);
        return report;
    }

    @Override
    public List<BloodTestInpatientlabEntity> getBySampleId(String bloodSampleId) {
        LambdaQueryWrapper<BloodTestInpatientlabEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodSampleId), BloodTestInpatientlabEntity::getBloodSampleInfoInpatientlabId, bloodSampleId)
                .eq(BloodTestInpatientlabEntity::getIfShow, IF_SHOW.code());
        return bloodTestInpatientlabDao.selectList(queryWrapper);
    }
}